<script lang="ts">
  import core, { Association, Doc, WithLookup } from '@hcengineering/core'
  import { IntlString } from '@hcengineering/platform'
  import { createQuery, getClient, ObjectCreate } from '@hcengineering/presentation'
  import { Button, IconAdd, Label, Scroller, Section, showPopup } from '@hcengineering/ui'
  import { showMenu } from '../actions'
  import { Viewlet, ViewletPreference, ViewOptions } from '@hcengineering/view'
  import DocTable from './DocTable.svelte'
  import ObjectBoxPopup from './ObjectBoxPopup.svelte'
  import view from '../plugin'
  import ViewletsSettingButton from './ViewletsSettingButton.svelte'

  export let object: Doc
  export let docs: Doc[]
  export let label: IntlString
  export let association: Association
  export let readonly: boolean = false
  export let direction: 'A' | 'B'
  export let emptyKind: 'create' | 'placeholder' = 'create'

  const client = getClient()

  $: _class = direction === 'B' ? association.classB : association.classA

  function getCreate (): ObjectCreate | undefined {
    const factory = client.getHierarchy().classHierarchyMixin(_class, view.mixin.ObjectFactory)
    if (factory) {
      return {
        component: factory.component,
        func: factory.create,
        label,
        props: { _class, space: object.space }
      }
    }
  }

  function add (): void {
    const create = getCreate()
    showPopup(
      ObjectBoxPopup,
      {
        _class,
        docQuery: { _id: { $nin: docs.map((p) => p._id) } },
        docProps: {
          shouldShowAvatar: true
        },
        create
      },
      'top',
      async (result) => {
        if (result != null) {
          const client = getClient()
          await client.createDoc(core.class.Relation, core.space.Workspace, {
            docA: direction === 'B' ? object._id : result._id,
            docB: direction === 'B' ? result._id : object._id,
            association: association._id
          })
        }
      }
    )
  }

  let viewlet: WithLookup<Viewlet> | undefined
  let preference: ViewletPreference | undefined = undefined

  $: baseClass = client.getHierarchy().getBaseClass(_class)

  $: selectedConfig = preference?.config ?? viewlet?.config
  $: config = selectedConfig?.filter((p) =>
    typeof p === 'string'
      ? !p.includes('$lookup') && !p.startsWith('@')
      : !p.key.includes('$lookup') && !p.key.startsWith('@')
  )

  async function onContextMenu (ev: MouseEvent, doc: Doc): Promise<void> {
    const q =
      direction === 'B'
        ? { docA: object._id, docB: doc._id, association: association._id }
        : { docA: doc._id, docB: object._id, association: association._id }
    const relation = await client.findOne(core.class.Relation, q)
    if (relation !== undefined) {
      showMenu(ev, { object: relation, includedActions: [view.action.RemoveRelation] })
    }
  }

  function isAllowedToCreate (association: Association, docs: Doc[], direction: 'A' | 'B'): boolean {
    if (docs.length === 0 || association.type === 'N:N') return true
    if (association.type === '1:1') return false
    return direction === 'B'
  }

  $: allowToCreate = isAllowedToCreate(association, docs, direction)

  $: classLabel = client.getHierarchy().getClass(_class).label
</script>

<Section {label}>
  <svelte:fragment slot="header">
    <div class="buttons-group xsmall-gap">
      {#if classLabel}
        <Label label={classLabel} />
      {/if}
      <ViewletsSettingButton viewletQuery={{ attachTo: baseClass }} kind={'tertiary'} bind:viewlet bind:preference />
      {#if !readonly && allowToCreate}
        <Button id={core.string.AddRelation} icon={IconAdd} kind={'ghost'} on:click={add} />
      {/if}
    </div>
  </svelte:fragment>

  <svelte:fragment slot="content">
    {#if docs?.length > 0 && config != null}
      <Scroller horizontal>
        <DocTable objects={docs} {_class} {config} {onContextMenu} />
      </Scroller>
    {:else if !readonly}
      <div
        class="antiSection-empty clear-mins mt-3"
        class:solid={emptyKind === 'create'}
        class:noBorder={emptyKind === 'placeholder'}
      >
        <!-- svelte-ignore a11y-click-events-have-key-events -->
        <!-- svelte-ignore a11y-no-static-element-interactions -->
        {#if emptyKind === 'create'}
          <span class="over-underline content-color" on:click={add}>
            <Label label={core.string.AddRelation} />
          </span>
        {:else}
          <span class=" content-color">
            <Label label={view.string.NoRelations} />
          </span>
        {/if}
      </div>
    {/if}
  </svelte:fragment>
</Section>
